package com.darcye.clear.work;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.darcye.clear.utils.DeleteLogger;
import com.darcye.clear.utils.FileList;
import com.darcye.clear.utils.ResRegex;
import com.darcye.clear.utils.ResUtil;

/**
 * 清理array 类型, 这里将会对位于res/values(*)下的全部文件进行扫描并清理
 * @author Darcy
 * @date 2014-10-10 上午10:11:31
 * @version V1.0
 */
public class ArrayWorker extends BaseWorker {

	private DeleteLogger logger = new DeleteLogger("Array");
	
	private final Set<String> mUsedArrayIdSet = new LinkedHashSet<String>();
	
	private final FilenameFilter mArrayFileFilter = new FilenameFilter() {
		public boolean accept(File file, String name) {
			File parentPath = file.getParentFile();
			return file.isFile() && parentPath!=null && parentPath.getName().startsWith("values");
		}
	};
	
	public ArrayWorker(JavaWorker javaWorker){
		mUsedArrayIdSet.addAll(javaWorker.getUsedArrayIdSet());
	}
	
	public void execute() {
		FileList fl = new FileList(getResourcePath());
		List<File> arrayFiles = fl.recurseListFiles(mArrayFileFilter);
		for (File arrayFile : arrayFiles) {
			handleFile(arrayFile);
		}
		logger.finish();
	}
	
	private boolean isArrayFileChange = false;
	
	private void handleFile(File arrayFile){
		Element rootEl;
		Document mDocument;
		try {
			isArrayFileChange = false;
			SAXBuilder builder = new SAXBuilder();
			mDocument = builder.build(arrayFile);
			rootEl = mDocument.getRootElement();
			obtainResIdsInArray(rootEl, "string-array", new OnObtainIdInArrayListener() {
				public void onObtained(String resValue) {
					if(resValue.matches(ResRegex.XML_STRING_REGEX)){
						mUsedStringIdSet.add(ResUtil.getIdName(resValue));
					}
				}
			});
			obtainResIdsInArray(rootEl, "integer-array",  new OnObtainIdInArrayListener() {
				public void onObtained(String resValue) {
					if(resValue.matches(ResRegex.XML_INTEGER_REGEX)){
						mUsedIntegerIdSet.add(ResUtil.getIdName(resValue));
					}
				}
			});
			obtainResIdsInArray(rootEl, "array",  new OnObtainIdInArrayListener() {
				public void onObtained(String resValue) {
					if(resValue.matches(ResRegex.XML_STRING_REGEX)){
						mUsedStringIdSet.add(ResUtil.getIdName(resValue));
					}else if(resValue.matches(ResRegex.XML_INTEGER_REGEX)){
						mUsedIntegerIdSet.add(ResUtil.getIdName(resValue));
					}else if(resValue.matches(ResRegex.XML_COLOR_REGEX)){
						mUsedColorIdSet.add(ResUtil.getIdName(resValue));
					}else if(resValue.matches(ResRegex.XML_DRAWABLE_REGEX)){
						mUsedDrawableIdSet.add(ResUtil.getIdName(resValue));
					}else if(resValue.matches(ResRegex.XML_BOOL_REGEX)){
						mUsedBoolIdSet.add(ResUtil.getIdName(resValue));
					}else if(resValue.matches(ResRegex.XML_DIMEN_REGEX)){
						mUsedDimenIdSet.add(ResUtil.getIdName(resValue));
					}
				}
			});
			if(isArrayFileChange && !isIgnoreDeleteFile(arrayFile)){
				backupDelFile(arrayFile);
				writeBack(arrayFile, mDocument);
			}
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void obtainResIdsInArray(Element rootEl,String tagName,OnObtainIdInArrayListener l){
		List<Element> resEls = rootEl.getChildren(tagName);
		List<Element> cloneResEls;
		List<Element> resElChildren;
		String resValue;
		String resName;
		if(resEls!=null && !resEls.isEmpty()){
			cloneResEls = new ArrayList<Element>(resEls);
			for (Element resEl : cloneResEls) {
				resName= resEl.getAttribute("name").getValue();
				if(!mUsedArrayIdSet.contains(resName)){
					isArrayFileChange = true;
					logger.log(resName);
					rootEl.removeContent(resEl);
					continue;
				}
				resElChildren = resEl.getChildren("item");
				if(resElChildren!=null){
					for (Element resElChild : resElChildren) {
						resValue = resElChild.getValue();
						if(l!=null)
							l.onObtained(resValue);
					}
				}
			}
		}
	}
	
	interface OnObtainIdInArrayListener{
		void onObtained(String resValue);
	}
}
